home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part2 / 13424 < prev    next >
Encoding:
Text File  |  1996-08-05  |  7.5 KB  |  261 lines

  1. Path: inforamp.net!ts4-03
  2. From: rmorin@inforamp.net (Randy Charles Morin)
  3. Newsgroups: comp.lang.c++
  4. Subject: TDocManager problems
  5. Date: Tue, 26 Mar 96 08:10:32 GMT
  6. Organization: MiddleWorld SoftWare
  7. Message-ID: <4j88qk$q74@sam.inforamp.net>
  8. NNTP-Posting-Host: ts4-03.tor.inforamp.net
  9. X-Newsreader: News Xpress Version 1.0 Beta #4
  10.  
  11. I had some problems with the behavior of OWL 2.5
  12. TDocManager.  I encapsulated the changes.
  13.  
  14. --------------------------------------------------------
  15. docman.h
  16. --------------------------------------------------------
  17. //{{TDocManager = MWDocManager}}
  18. class MWDocManager : public TDocManager {
  19. public:
  20.     MWDocManager (int mode, TApplication* app);
  21.      virtual ~MWDocManager ();
  22. protected:
  23.     virtual int SelectDocPath(TDocTemplate** tpllist, int tplcount,
  24.                   char far* path, int buflen, long flags, bool 
  25. save);
  26. protected:
  27. //    TApplication * pApplication;
  28.  
  29. //{{MWDocManagerVIRTUAL_BEGIN}}
  30. public:
  31.     virtual TDocTemplate* SelectAnySave (TDocument& doc, bool samedoc = true);
  32. //{{MWDocManagerVIRTUAL_END}}
  33. };    //{{MWDocManager}}
  34. ----------------------------------------------------------
  35. docman.cpp
  36. ----------------------------------------------------------
  37. #ifndef MW_DOCMAN_H
  38. #include "docman.h"
  39. #endif
  40. #ifndef __DIR_H
  41. #include <dir.h>
  42. #endif
  43. #ifndef _DLGSH_INCLUDED_
  44. #include <dlgs.h>
  45. #endif
  46.  
  47.  
  48. //{{MWDocManager Implementation}}
  49.  
  50.  
  51. MWDocManager::MWDocManager (int mode, TApplication* app):
  52.      TDocManager(mode, app)
  53. {
  54.     // INSERT>> Your constructor code here.
  55.  
  56. }
  57.  
  58.  
  59. MWDocManager::~MWDocManager ()
  60. {
  61.      // INSERT>> Your destructor code here.
  62.  
  63. }
  64.  
  65. //
  66. //  struct to pass data to the dialog hook function via OPENFILENAME.lCustData
  67. //  under Win32s the OPENFILENAME passed to WM_INITDIALOG is a temporary copy
  68. //
  69. struct TplHookData {      // pointer to this struct passed as lCustData
  70.   long Flags;             // original flags passed to SelectDocPath
  71.   unsigned long far* DlgFlags;     // pointer to dialog flags in OPENFILENAME
  72.   char far* ExtBuf;       // pointer to buffer holding the default extension
  73.   TDocTemplate** TplList; // template pointer array
  74.   int InitIndex;          // starting index, ofn.nFilterIndex is inconsistent
  75.   bool Save;              // true if saving
  76. };
  77.  
  78. //
  79. //  dialog hook function to catch template selection changes
  80. //
  81. uint CALLBACK __export
  82. TplHook(HWND hDlg, uint msg, uint wParam, int32 lParam)
  83. {
  84.   static TplHookData* hookData;  // !!update to store in dialog property
  85.   TDocTemplate** tpllist;
  86.   OPENFILENAME* ofnHook;
  87.   int idx;
  88.   switch(msg) {
  89.     case WM_COMMAND:
  90. #if defined(BI_PLAT_WIN32)
  91.       if (LOWORD(wParam) != cmb1 || HIWORD(wParam) != CBN_SELCHANGE)
  92. #else
  93.         if (wParam != cmb1 || HIWORD(lParam) != CBN_SELCHANGE)
  94. #endif
  95.         return 0;
  96.       idx = (int)::SendMessage((HWND)(uint)lParam, CB_GETCURSEL, 0, 0L);
  97.       break;
  98.  
  99.     case WM_INITDIALOG:
  100.       ofnHook = (OPENFILENAME*)lParam;
  101.       hookData = (TplHookData*)ofnHook->lCustData;
  102.       idx = hookData->InitIndex;  // can't rely upon ofnHook->nFilterIndex
  103.       break;
  104.  
  105.     default:
  106.       return 0;
  107.   }
  108.   tpllist = hookData->TplList;
  109.   long flags = tpllist[idx]->GetFlags() | hookData->Flags;
  110.   if (hookData->Save)
  111.      flags = (flags | dtNoReadOnly) & ~dtFileMustExist;
  112.   *hookData->DlgFlags = flags & ~dtProhibited;
  113.   if (tpllist[idx]->GetDefaultExt())
  114.     strcpy(hookData->ExtBuf, tpllist[idx]->GetDefaultExt());
  115.   else
  116.     hookData->ExtBuf[0] = 0;
  117.   ::SendDlgItemMessage(hDlg, chx1, BM_SETCHECK, ((flags&dtReadOnly) != 0), 0);
  118.   ::ShowWindow(GetDlgItem(hDlg, chx1), 
  119. (flags&dtHideReadOnly)?SW_HIDE:SW_SHOW);
  120.   return 0;  // flag as unprocessed
  121. }
  122.  
  123. //  prompts user with one or all templates to select file to open
  124. //  returns the template index used for the selection (1-based), 0 if failure
  125. //  this is Windows-specific, using the system-defined file open dialog box
  126. //
  127. int
  128. MWDocManager::SelectDocPath(TDocTemplate** tpllist, int tplcount,
  129.                   char far* path, int buflen, long flags, bool 
  130. save)
  131. {
  132.   char extbuf[MAXEXT-1];       // writable buffer for default file extension
  133.   OPENFILENAME ofn;            // local openfilename structure
  134.   int index, count, len;
  135.   char* filtbuf;
  136.   char* pbuf;
  137.   memset(&ofn, 0, sizeof(ofn));
  138.   TDocTemplate* ptpl;
  139.   TProcInstance TplHookProcInstance((FARPROC)TplHook);
  140.  
  141.   // Concatenate description and filters into a single string
  142.   //
  143.   for (len=2, count=0; count < tplcount; count++) {
  144.      ptpl = tpllist[count];
  145.     len += (strlen(ptpl->GetFileFilter())+2); // space for two null separators
  146.     if (ptpl->GetDescription())
  147.       len += strlen(ptpl->GetDescription());
  148.   }
  149.   filtbuf = new char[len];
  150.   for (pbuf = filtbuf, count=0; count < tplcount; count++) {
  151.     ptpl = tpllist[count];
  152.     if ((len = strlen(ptpl->GetDescription())) != 0) {
  153.       strcpy(pbuf, ptpl->GetDescription());
  154.       pbuf += len + 1;
  155.     }
  156.     else {
  157.       *pbuf++ = 0;
  158.     }
  159.      strcpy(pbuf, ptpl->GetFileFilter());
  160.     pbuf += strlen(pbuf) + 1;
  161.   }
  162.   *pbuf = 0;              // double null to signify end
  163.  
  164.   // set selection to previously selected template if present
  165.   //
  166.   index=tplcount-1;
  167.  
  168.   struct TplHookData hookData = {flags,&ofn.Flags,extbuf,tpllist,index,save};
  169.   ofn.nFilterIndex = index + 1; // Note: Windows *might* decrement this by one
  170.   ofn.lpstrInitialDir = tpllist[index]->GetDirectory();
  171.   ofn.lpstrDefExt = (LPCSTR)&extbuf;  // receives string from hook function
  172.   ofn.lStructSize = sizeof(OPENFILENAME);
  173.   ofn.hwndOwner = GetApplication()->GetMainWindow()->HWindow;
  174.   ofn.lpstrFilter = filtbuf;
  175.   ofn.lpstrFile = path;
  176.   ofn.nMaxFile = buflen;
  177.   ofn.Flags = OFN_ENABLEHOOK;
  178.   ofn.lCustData = (LPARAM)&hookData;
  179.   (DLGPROC)ofn.lpfnHook = (DLGPROC)(FARPROC)TplHookProcInstance;
  180.  
  181.   GetApplication()->EnableCtl3dAutosubclass(true);
  182.  
  183.   if ((save ? ::GetSaveFileName(&ofn) : ::GetOpenFileName(&ofn)) == 0) {
  184.      uint32 err = ::CommDlgExtendedError();  // temp for debugging use
  185.      if (err != 0)
  186.         TRACEX(OwlDocView, 0, "OpenFileName error:" << err);
  187.      ofn.nFilterIndex = 0;
  188.   }
  189.   else
  190.   {
  191.      // Set flag to remember template which was selected
  192.      //
  193.      for (index=(int)ofn.nFilterIndex-1, count=0; count < tplcount; 
  194. count++) {
  195.       if (count == index)
  196.         tpllist[count]->SetFlag(dtSelected);
  197.       else
  198.           tpllist[count]->ClearFlag(dtSelected);
  199.     }
  200.      // Update template with directory from dialog if flag set
  201.      //
  202.      ptpl = tpllist[(int)ofn.nFilterIndex - 1];
  203.      if (ofn.nFileOffset && (ptpl->IsFlagSet(dtUpdateDir))
  204.                                 && 
  205. (ptpl->GetDirectory()==0
  206.             || memcmp(ptpl->GetDirectory(), 
  207. ofn.lpstrFile,ofn.nFileOffset) != 0))
  208.         ptpl->SetDirectory(ofn.lpstrFile, ofn.nFileOffset);
  209.   }
  210.   delete [] filtbuf;
  211.   GetApplication()->EnableCtl3dAutosubclass(false);
  212.   return (int)ofn.nFilterIndex;
  213. }
  214.  
  215.  
  216. TDocTemplate* MWDocManager::SelectAnySave (TDocument& doc, bool)
  217. {
  218. //    TDocTemplate* result;
  219.  
  220. //    result = TDocManager::SelectAnySave(doc, samedoc);
  221.  
  222.      // INSERT>> Your code here.
  223.   TDocTemplate* ptpl;
  224.   char filepath[256];
  225.   int index;
  226.   TDocTemplate* tpllist[2];
  227.   tpllist[0] = doc.GetTemplate();
  228.   int tplcount=1;
  229.  
  230.   if (doc.GetDocPath())
  231.      strcpy(filepath, doc.GetDocPath());
  232.   else
  233.      filepath[0] = 0;    // no initial file path
  234.   index = SelectDocPath(tpllist, tplcount, filepath, sizeof(filepath),0,true);
  235.   if (!index)
  236.      return 0;   // user cancel or dialog error
  237.   ptpl = tpllist[index-1];
  238.   if (!doc.SetDocPath(filepath))
  239.      return 0;
  240.   return ptpl;
  241.  
  242. //     return result;
  243. }
  244. --------------------------------------------------------
  245.  
  246. don't forget to call
  247.     SetDocManager(new MWDocManager(dmMDI, this));
  248. in your TApplication constructor
  249.  
  250. Hope this helps somebody
  251.  
  252. Agrivar
  253.  
  254.  
  255. Agrivar
  256.  
  257. aka     Randy Charles Morin
  258.     MiddleWorld SoftWare
  259.     Canada: 1-800-363-3780
  260.     Other:    905-279-2087
  261.